#!/bin/sh
#
# Copyright (C) 2000-2025 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Run a simple backup of the Bacula build directory then create some           
#   new files, do an Incremental and restore those two files.
# test the bvfs interface
#
TestName="bvfs-test"
JobName=Incremental 
. scripts/functions

${rscripts}/cleanup
${rscripts}/copy-test-confs
echo "${tmpsrc}" >${tmp}/file-list
echo "${cwd}/build" >> ${tmp}/file-list

mkdir -p ${tmpsrc}
cp -p ${src}/src/dird/*.c ${tmpsrc}
mkdir $tmpsrc/directory
echo test > $tmpsrc/directory/1
cd ${tmp}
echo "${tmpsrc}/ficheriro1.txt" >restore-list
echo "${tmpsrc}/ficheriro2.txt" >>restore-list
cd ${cwd}

change_jobname CompressedTest $JobName
start_test

cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
sql
SELECT pg_catalog.setval('file_fileid_seq', 21474836471, false);

@$out ${tmp}/log1.out
label storage=File volume=TestVolume001
label storage=File volume=TestVolume002
run job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bacula
check_for_zombie_jobs storage=File
#
# Now create two new files to be restored later
#
sleep 1
echo "ficheriro1.txt" >${tmpsrc}/ficheriro1.txt
cp -f ${tmpsrc}/dird.c ${tmpsrc}/ficheriro2.txt

cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
@# Force Incremental on the second Volume
update volume=TestVolume001 VolStatus=Used
run level=Differential job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bconsole

sleep 1
touch ${tmpsrc}/ficheriro1.txt
touch ${tmpsrc}/ficheriro2.txt

cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Incremental job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bconsole

sleep 1
cd ${tmpsrc}
cp -f ficheriro2.txt 1
sed "s%a%b%g" 1 >ficheriro2.txt
rm -f 1
rm -rf directory
cd ${cwd}
cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Differential accurate=yes job=$JobName yes
wait
messages
@$out $tmp/log35.out
.bvfs_update jobid=1,2,3,4
.bvfs_lsdir jobid=1,2,3 path=$tmp/build/
.bvfs_lsdir jobid=1,4 path=$tmp/build/
@$out $tmp/log36.out
sql
SELECT * FROM PathVisibility JOIN Path USING (PathId) WHERE JobId=4;

quit
END_OF_DATA

run_bconsole

sleep 1
touch ${tmpsrc}/ficheriro1.txt
touch ${tmpsrc}/ficheriro2.txt
cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Incremental job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bconsole

sleep 1
touch ${tmpsrc}/ficheriro1.txt
touch ${tmpsrc}/ficheriro2.txt
cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Incremental job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bconsole

sleep 1
touch ${tmpsrc}/ficheriro1.txt
touch ${tmpsrc}/ficheriro2.txt
cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Incremental job=$JobName yes
wait
messages
quit
END_OF_DATA

run_bconsole
sleep 1
cat /etc/hosts >> ${tmpsrc}/ficheriro1.txt
rm -f ${tmpsrc}/dird_conf.c
touch ${tmpsrc}/ficheriro2.txt
ln ${tmpsrc}/ficheriro2.txt ${tmpsrc}/hardlink2

# A linux system has 2000 symlinks
for i in `seq 1 4000`
do
    cat /etc/hosts > ${tmpsrc}/file$i.txt
    ln ${tmpsrc}/file$i.txt ${tmpsrc}/hl.$i
done

for i in `seq 1 50`
do
    ln ${tmpsrc}/file$i.txt ${tmpsrc}/hl2.$i
done

cat <<END_OF_DATA >${tmp}/bconcmds
@$out /dev/null
messages
@$out ${tmp}/log1.out
run level=Incremental accurate=yes job=$JobName
yes
wait
messages
@$out ${tmp}/log3.out
.bvfs_update
.bvfs_lsdir path=$tmpsrc/ jobid=1,2,3,4,5,6,7,8
.bvfs_lsfile path=$tmpsrc/ jobid=1,2,3,4,5,6,7,8 limit=5000
@$out ${tmp}/log31.out
.bvfs_lsfile path=$tmpsrc/ jobid=1,2,3,4,5,6,7 limit=5000
@$out ${tmp}/log32.out
.bvfs_lsfile path=$tmpsrc/ jobid=1,2,3,4,5,6,7,8 filename=ficheriro1.txt
quit
END_OF_DATA

run_bconsole

cat <<END_OF_DATA >${tmp}/bconcmds
@$out $tmp/log4.out
.bvfs_cleanup path=b21
END_OF_DATA


# we look in the lsdir/lsfiles output to get filenameid and pathid for version and restore
awk '/ficheriro1.txt/ { 
  print ".bvfs_versions jobid=" $4 " fnid=" $2 " pathid=" $1 " client='$CLIENT'"
  print ".bvfs_restore jobid=" $4 " fileid=" $3 " path=b21"
} ' $tmp/log3.out >> $tmp/bconcmds

cat <<END_OF_DATA >>${tmp}/bconcmds
restore file="?b21" where=$tmp/bacula-restores yes
wait
messages
quit
END_OF_DATA

run_bconsole

diff $tmpsrc/ficheriro1.txt $tmp/bacula-restores/$tmpsrc/ficheriro1.txt > $tmp/d1 2>&1 
if [ $? != 0 ]; then
    print_debug "ERROR: ficheriro1.txt is different"
    rstat=1
fi

rm -rf $tmp/bacula-restores

cat <<END_OF_DATA >${tmp}/bconcmds
@$out $tmp/log4.out
@# Try to restore a directory
.bvfs_cleanup path=b21
END_OF_DATA

awk '/ficheriro2.txt/ { 
  print ".bvfs_restore jobid=1,2,3,4,5,6,7,8 dirid=" $1 " path=b21"
} ' $tmp/log3.out >> $tmp/bconcmds

cat <<END_OF_DATA >>${tmp}/bconcmds
@$out $tmp/log2.out
restore file="?b21" where=$tmp/bacula-restores yes
wait
messages
quit
END_OF_DATA

run_bconsole

$rscripts/diff.pl -s $tmpsrc/ -d $tmp/bacula-restores/$tmpsrc/
if [ $? != 0 ]; then
    print_debug "ERROR: Found error while restoring a directory"
    rstat=1
fi

diff $tmpsrc/ficheriro2.txt $tmp/bacula-restores/$tmpsrc/ficheriro2.txt
if [ $? != 0 ]; then
    print_debug "ERROR: ficheriro2.txt is different"
    rstat=1
fi

rm -rf $tmp/bacula-restores

cat <<END_OF_DATA >${tmp}/bconcmds
@$out $tmp/log4.out
@# Try to restore a hardlinks
.bvfs_cleanup path=b21
END_OF_DATA

# We get the last of ficheriro2.txt and hardlink2 to get the LinkFI
jidx=`awk -F '\t' '/ficheriro2.txt|hardlink2/ { print "@echo fileid=" $3; print ".bvfs_decode_lstat lstat=\"" $5 "\"" } ' $tmp/log3.out | $bin/bconsole -c $conf/bconsole.conf | awk -F= '/LinkFI=[1-9][0-9]*/ { print $2 } '`

fileid=`awk -F '\t' '/ficheriro2.txt|hardlink2/ { print "@echo fileid=" $3; print ".bvfs_decode_lstat lstat=\"" $5 "\"" } ' $tmp/log3.out | $bin/bconsole -c $conf/bconsole.conf | awk -F= '/fileid=/ { fileid=$2 } /LinkFI=[1-9][0-9]*/ { print fileid } '`

# We take the last between ficheriro2.txt and hardlink2, and we restore both via the hardlink command
echo ".bvfs_restore jobid=1,2,3,4,5,6,7,8 hardlink=8,$jidx fileid=$fileid path=b21" >> $tmp/bconcmds

cat <<END_OF_DATA >>${tmp}/bconcmds
@$out $tmp/log2.out
restore file="?b21" where=$tmp/bacula-restores yes
wait
messages
quit
END_OF_DATA

run_bconsole

test -f $tmp/bacula-restores/$tmpsrc/hardlink2 -a -f $tmp/bacula-restores/$tmpsrc/ficheriro2.txt
if [ $? != 0 ]; then
    print_debug "ERROR: Need to get all files"
    rstat=1
fi

# Compare Inode
ls -i $tmp/bacula-restores/$tmpsrc/hardlink2 | awk ' { print $1 } ' > $tmp/1
ls -i $tmp/bacula-restores/$tmpsrc/ficheriro2.txt | awk ' { print $1 } ' > $tmp/2
diff $tmp/1 $tmp/2 > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: Both files should have the same inode number"
    rstat=1
fi

check_for_zombie_jobs storage=File
stop_bacula

check_two_logs

grep dird_conf.c $tmp/log3.out > /dev/null
if [ $? = 0 ]; then
    print_debug "ERROR: Should not find dird_conf.c in bvfs_lsfiles output $tmp/log3.out"
    estat=1
fi

grep dird_conf.c $tmp/log31.out > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: Should find dird_conf.c in bvfs_lsfiles output $tmp/log31.out"
    estat=1
fi

awk '/\tficheriro1.txt/ { print "ok"} ' $tmp/log32.out | grep ok > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: Should find ficheriro1.txt in bvfs_lsfiles output $tmp/log32.out"
    estat=1
fi

nb=`grep directory/ $tmp/log35.out | wc -l`
if [ $nb != 1 ]; then
    print_debug "ERROR: Should find only one time directory/ in $tmp/log35.out"
    estat=1
fi

nb=`grep directory/ $tmp/log36.out | wc -l`
if [ $nb != 0 ]; then
    print_debug "ERROR: Should not find directory/ in $tmp/log36.out"
    estat=1
fi

#
# Delete .c files because we will only restored the txt files
#
#rm -f ${tmpsrc}/*.c
#check_restore_tmp_build_diff
#
#${cwd}/build/src/tools/bvfs_test -T  -p ${tmpsrc} -j 1,2,3,4,5,6,7,8 \
#    -w "$working" -n "$db_name" -u "$db_user" -P "$db_password"
#
#${cwd}/build/src/tools/bvfs_test  -p ${cwd}/build/ -j 1,2,3,4,5,6,7,8    \
#    -w "$working" -n "$db_name" -u "$db_user" -P "$db_password" 
#
#${cwd}/build/src/tools/bvfs_test  -p ${tmpsrc} -j 1,2,3,4,5,6,7,8    \
#    -w "$working" -n "$db_name" -u "$db_user" -P "$db_password" \
#    -f ficheriro1.txt -c ${HOST}-fd

end_test
